package com.songlanyun.modules.usercard.service.impl;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.utils.BeanUtil;
import com.songlanyun.common.utils.OrderGen;
import com.songlanyun.modules.account.entity.AccountEntity;
import com.songlanyun.modules.account.entity.UserVerifiedEntity;
import com.songlanyun.modules.account.service.AccountService;
import com.songlanyun.modules.account.service.UserVerifiedService;
import com.songlanyun.modules.user.exception.UserException;
import com.songlanyun.modules.usercard.mobel.UserCardConfirmDto;
import com.songlanyun.modules.usercard.mobel.UserCardDto;
import com.songlanyun.modules.usercard.mobel.UserCardRemoveDto;
import com.songlanyun.pay.bean.AdaCardBean;
import com.songlanyun.pay.bean.AdaCardConfirmBean;
import com.songlanyun.pay.bean.AdaMemberBean;
import com.songlanyun.pay.bean.AdaRemoveCardBean;
import com.songlanyun.pay.service.AdaKjPayService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.songlanyun.common.utils.PageUtils;
import com.songlanyun.common.utils.Query;

import com.songlanyun.modules.usercard.dao.UserCardDao;
import com.songlanyun.modules.usercard.entity.UserCardEntity;
import com.songlanyun.modules.usercard.service.UserCardService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;


@Service("userCardService")
public class UserCardServiceImpl extends ServiceImpl<UserCardDao, UserCardEntity> implements UserCardService {

    @Autowired
    AccountService accountService;

    @Autowired
    UserVerifiedService userVerifiedService;

    @Resource
    private AdaKjPayService adaKjPayService;

    @Override
    public UserCardEntity create(UserCardEntity entity) {
        this.baseMapper.insert(entity);
        return entity;
    }

    @Override
    public UserCardEntity modify(UserCardEntity entity) {
        this.baseMapper.updateById(entity);
        return entity;
    }

    @Override
    public void remove(Long id) {

    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<UserCardEntity> page = this.page(
                new Query<UserCardEntity>().getPage(params),
                new QueryWrapper<UserCardEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public UserCardEntity loadById(Long id, boolean tw) {
        UserCardEntity obj = this.getById(id);
        if (ObjectUtil.isNull(obj) && tw) {
            throw new RRException(UserException.USER_CARD_NOT_EXISTS);
        }
        return obj;
    }

    @Override
    public UserCardEntity loadByApplyId(String applyId, boolean tw) {
        UserCardEntity obj = this.baseMapper.selectOne(new LambdaQueryWrapper<UserCardEntity>().eq(UserCardEntity::getApplyCardId, applyId).last("limit 1"));
        if (ObjectUtil.isNull(obj) && tw) {
            throw new RRException(UserException.USER_CARD_NOT_EXISTS);
        }
        return obj;
    }

    @Override
    public void delete(UserCardRemoveDto dto) {
        UserCardEntity userCardEntity = this.loadByUserIdAndId(dto.getUserId(),dto.getId(), true);
        if (!userCardEntity.getValid()) {
            this.baseMapper.deleteById(userCardEntity.getId());
            return;
        }
        AdaRemoveCardBean adaRemoveCardBean = new AdaRemoveCardBean();
        adaRemoveCardBean.setMemberId(userVerifiedService.getKjMemberId(userCardEntity.getUserId()));
        adaRemoveCardBean.setTokenNo(userCardEntity.getTokenNo());
        adaRemoveCardBean.setOrderNo(OrderGen.generateOrderNo());
        try {
            adaKjPayService.unBindCard(adaRemoveCardBean, (o) -> {
                this.baseMapper.deleteById(dto.getId());
                return null;
            });
        } catch (Exception ex) {
            throw new RRException(ex.getMessage());
        }
    }

    private UserCardEntity loadByMemberIdAndTokenNo(String memberId, String tokenNo)
    {
        String[] arr = StringUtils.split(memberId, "_");
        if(arr.length!=2)
        {
            throw new RRException("回调的MemberId错误"+memberId);
        }
        UserCardEntity userCardEntity = this.baseMapper.selectOne(new LambdaQueryWrapper<UserCardEntity>()
                .eq(UserCardEntity::getUserId, Long.valueOf(arr[1])).eq(UserCardEntity::getTokenNo, tokenNo).last("limit 1"));
        if (ObjectUtil.isNull(userCardEntity)) {
            throw new RRException(UserException.USER_CARD_NOT_EXISTS);
        }
        return userCardEntity;
    }

    private UserCardEntity loadByMemberIdAndApplyId(String memberId, String applyId)
    {
        String[] arr = StringUtils.split(memberId, "_");
        if(arr.length!=2)
        {
            throw new RRException("回调的MemberId错误"+memberId);
        }
        UserCardEntity userCardEntity = this.baseMapper.selectOne(new LambdaQueryWrapper<UserCardEntity>()
                .eq(UserCardEntity::getUserId, Long.valueOf(arr[1])).eq(UserCardEntity::getApplyCardId, applyId).last("limit 1"));
        if (ObjectUtil.isNull(userCardEntity)) {
            throw new RRException(UserException.USER_CARD_NOT_EXISTS);
        }
        return userCardEntity;
    }

    @Override
    public void deleteByToKenNo(String memberId, String tokenNo) {
        UserCardEntity userCardEntity = this.loadByMemberIdAndTokenNo(memberId, tokenNo);
        if (ObjectUtil.isNull(userCardEntity) ) {
            throw new RRException(UserException.USER_CARD_NOT_EXISTS);
        }
        this.baseMapper.deleteById(userCardEntity.getId());
    }

    @Override
    public void setNoValidByTokenNo(String memberId, String tokenNo) {
        UserCardEntity userCardEntity = this.loadByMemberIdAndTokenNo(memberId, tokenNo);
        if (ObjectUtil.isNull(userCardEntity) ) {
            throw new RRException(UserException.USER_CARD_NOT_EXISTS);
        }
        userCardEntity.setValid(false);
        this.modify(userCardEntity);
    }

    @Override
    public List<UserCardEntity> loadList(Long userId, Integer valid) {
        List<UserCardEntity> userCardEntities = this.baseMapper.selectList(new LambdaQueryWrapper<UserCardEntity>()
                .eq(UserCardEntity::getUserId, userId)
                .eq(valid > -1, UserCardEntity::getValid, valid)
                .orderByDesc(UserCardEntity::getValid));
        return userCardEntities;
    }

    @Override
    public UserCardEntity loadByUserIdAndId(Long userId, Long id, boolean tw) {
        UserCardEntity obj = this.baseMapper.selectOne(new LambdaQueryWrapper<UserCardEntity>().eq(UserCardEntity::getId, id)
                .eq(UserCardEntity::getUserId, userId).last("limit 1"));
        if (ObjectUtil.isNull(obj) && tw) {
            throw new RRException(UserException.USER_CARD_NOT_EXISTS);
        }
        return obj;
    }

    @Override
    @Transactional()
    public UserCardEntity add(Long userId, UserCardDto dto) {
        AccountEntity account = accountService.getUserById(userId, true);
        UserVerifiedEntity userVerifiedEntity = userVerifiedService.loadById(userId, true);
        valiDateRepeat(dto);


        if (!userVerifiedEntity.getUploadKj()) {

            AdaMemberBean bean = new AdaMemberBean();
            bean.setMemberId(userVerifiedService.getKjMemberId(userVerifiedEntity.getId()));
            try {
                adaKjPayService.selectAdaMember(bean,(o)->{
                    userVerifiedEntity.setUploadKj(true);
                    userVerifiedService.updateById(userVerifiedEntity);
                    return null;
                });

            } catch (Exception ex) {
                //throw new RRException(ex.getMessage());
            }

            if(!userVerifiedEntity.getUploadKj()) {
                bean = new AdaMemberBean();
                bean.setUserName(userVerifiedEntity.getRealName());
                bean.setTelNo(account.getMobile());
                bean.setCertType("00");
                bean.setCertId(userVerifiedEntity.getIdentityNumber());
                bean.setMemberId(userVerifiedService.getKjMemberId(userVerifiedEntity.getId()));
                try {
                    adaKjPayService.createAdaMember(bean, (o) -> {
                        userVerifiedEntity.setUploadKj(true);
                        userVerifiedService.updateById(userVerifiedEntity);
                        return null;
                    });

                } catch (Exception ex) {
                    throw new RRException(ex.getMessage());
                }
            }

            ThreadUtil.sleep(200, TimeUnit.MILLISECONDS);
        }

        if (dto.getCredit()) {
            if (StringUtils.isEmpty(dto.getVipCode())) {
                throw new RRException(UserException.USER_CARD_NOT_EXISTS);
            }
            if (StringUtils.isEmpty(dto.getExpiration())) {
                throw new RRException(UserException.USER_CARD_EXPIRATION_NEED);
            }
        }
        UserCardEntity userCardEntity = new UserCardEntity();
        BeanUtil.copyPropertiesIgnoreNull(dto, userCardEntity);
        userCardEntity.setUserId(userId);
        userCardEntity.setValid(false);

        this.create(userCardEntity);
        AdaCardBean adaCardBean = new AdaCardBean();
        adaCardBean.setCardId(userCardEntity.getCardId());
        adaCardBean.setMemberId(userVerifiedService.getKjMemberId(userVerifiedEntity.getId()));
        adaCardBean.setTelNo(userCardEntity.getTelNo());
        adaCardBean.setVipCode(userCardEntity.getVipCode());
        adaCardBean.setExpiration(userCardEntity.getExpiration());
        adaCardBean.setProtocolNo(userCardEntity.getProtocolNo());
        try {
            Map<String, Object> cardApply = adaKjPayService.createCardApply(adaCardBean);
            Object id = cardApply.get("id");
            if (ObjectUtil.isNotEmpty(id)) {
                userCardEntity.setApplyCardId(id.toString());
                this.modify(userCardEntity);
            }
        } catch (Exception ex) {
            throw new RRException(ex.getMessage());
        }
        return userCardEntity;
    }

    private void valiDateRepeat(UserCardDto dto) {
        Integer num = this.baseMapper.selectCount(new LambdaQueryWrapper<UserCardEntity>().eq(UserCardEntity::getCardId, dto.getCardId()));
        if(num>0)
        {
            throw new RRException("该银行卡已被您或他人使用过");
        }
    }

    @Override
    public void createCardConfirm(Long userId, UserCardConfirmDto dto) {
        UserCardEntity userCardEntity = this.loadByUserIdAndId(userId, dto.getId(), true);
        AdaCardConfirmBean adaCardConfirmBean = new AdaCardConfirmBean();
        adaCardConfirmBean.setApplyId(userCardEntity.getApplyCardId());
        adaCardConfirmBean.setSmsCode(dto.getSmsCode());
        try {
            adaKjPayService.createCardConfirm(adaCardConfirmBean, (o) -> {
                Map<String, Object> r = (Map<String, Object>)o;
                Object tokenNo = r.get("token_no");
                Object bankName = r.get("bank_name");
                boolean isUpdate = false;
                if(ObjectUtil.isNotEmpty(bankName)) {
                    isUpdate = true;
                    userCardEntity.setBankName(bankName.toString());
                }
                if(ObjectUtil.isNotEmpty(tokenNo)) {
                    userCardEntity.setTokenNo(tokenNo.toString());
                    userCardEntity.setValid(true);
                    isUpdate = true;
                }
                if(isUpdate) {
                    this.modify(userCardEntity);
                }

                return null;
            });
        } catch (Exception ex) {
            throw new RRException(ex.getMessage());
        }
    }

    @Override
    public void setValidAndTokenNo(String memberId,String applyId, String tokenNo) {
        UserCardEntity userCardEntity = this.loadByMemberIdAndApplyId(memberId,applyId);
        if(ObjectUtil.isNull(userCardEntity))
        {
            throw new RRException(UserException.USER_CARD_NOT_EXISTS);
        }
        userCardEntity.setTokenNo(tokenNo);
        userCardEntity.setValid(true);
        this.modify(userCardEntity);
    }

    @Override
    public void setNoValidAndTokenNo(String memberId,String applyId) {
        UserCardEntity userCardEntity = this.loadByMemberIdAndApplyId(memberId,applyId);
        if(ObjectUtil.isNull(userCardEntity))
        {
            throw new RRException(UserException.USER_CARD_NOT_EXISTS);
        }
        userCardEntity.setValid(true);
        this.modify(userCardEntity);
    }

}
